Skip to content

Conversation

@zbeyens
Copy link
Member

@zbeyens zbeyens commented Oct 30, 2025

Summary

Adds support for custom mutation builders in createClient and createApi, enabling consumers to wrap internal mutations with custom context such as triggers, aggregates, or middleware.

Changes

  • src/client.ts: Added optional internalMutation parameter to createClient config

    • All 6 trigger mutations (beforeCreate, beforeDelete, beforeUpdate, onCreate, onDelete, onUpdate) now use the custom builder when provided
  • src/api.ts: Added optional internalMutation parameter merged with authOptions

    • All 5 CRUD mutations (create, updateOne, updateMany, deleteOne, deleteMany) use the custom builder when provided
  • README.md: Added comprehensive documentation

    • New "Custom Mutation Builders" section with use cases and examples
    • Inline comments in main setup example
  • .changeset/custom-mutation-builder.md: Added changeset for patch release

Use Cases

This feature enables:

  • Wrapping database operations with trigger systems (e.g., @convex/triggers)
  • Applying middleware to all auth mutations
  • Injecting custom context or dependencies
  • Adding logging, monitoring, or analytics

Example Usage

import { customMutation, customCtx } from 'convex-helpers/server/customFunctions';
import { internalMutationGeneric } from 'convex/server';
import { registerTriggers } from '@convex/triggers';

const triggers = registerTriggers();

// Wrap mutations to include trigger-wrapped database
const internalMutation = customMutation(
  internalMutationGeneric,
  customCtx(async (ctx) => ({
    db: triggers.wrapDB(ctx).db,
  }))
);

// Pass to createClient
export const authClient = createClient<DataModel, typeof schema>({
  authFunctions,
  schema,
  internalMutation, // Custom builder
  triggers: { ... }
});

// Pass to createApi
export const { create, updateOne, ... } = createApi(schema, {
  ...auth.options,
  internalMutation, // Same custom builder
});

Backward Compatibility

✅ Fully backward compatible - internalMutation is optional and defaults to internalMutationGeneric

Testing

  • Type checking passes
  • Maintains existing API surface
  • No breaking changes

🤖 Generated with Claude Code

Co-Authored-By: Claude [email protected]

Add optional internalMutation parameter to both createClient and createApi,
allowing consumers to wrap internal mutations with custom context (triggers,
aggregates, middleware). All auth operations (CRUD + triggers) now use the
custom builder when provided.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@changeset-bot
Copy link

changeset-bot bot commented Oct 30, 2025

🦋 Changeset detected

Latest commit: df53a30

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
better-auth-convex Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@zbeyens zbeyens merged commit d58bb8f into main Oct 30, 2025
1 check passed
@zbeyens zbeyens deleted the feat/custom-mutation-builder branch October 30, 2025 19:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants